import { get } from "ol/proj";
import { getWidth, getTopLeft } from "ol/extent";
import XYZ from "ol/source/XYZ";
import TileGrid from "ol/tilegrid/TileGrid";
import { Tile as LayerTile } from "ol/layer";

// 天地图密钥
const TK = "89d2cf60059b2e465404afbd1f108401";

// 获取天地图地址
const getUrl = function (type: string) {
	let url = "http://t{randomNumber}.tianditu.gov.cn/DataServer?T={type}&x={x}&y={y}&l={z}";
	// 这里用随机数获取地址
	url = url.replace("{randomNumber}", Math.round(Math.random() * 7).toString());
	url = url.replace("{type}", type);
	url = url + "&tk=" + TK;
	return url;
};

// 获取分辨率数组，根据缩放级别切换分辨率
const getResolutionsExpert = function (size: number) {
	const resolutions = new Array(18);
	const matrixIds = new Array(18);
	for (let z = 0; z < 19; ++z) {
		// 分辨率
		resolutions[z] = size / Math.pow(2, z);
		// 等级
		matrixIds[z] = z;
	}
	return resolutions;
};

const getOptional = function (url: string, proj: string) {
	// 获取4326或者3857格式的投影坐标系
	const projection: any = get(proj);
	// 获取坐标系的范围
	const projectionExtent = projection?.getExtent();
	// 根据坐标系范围设置切片大小
	const size = getWidth(projectionExtent) / 256;

	// 以XYZ形式获取资源数据
	return new XYZ({
		// 允许跨域获取图片资源，与img的crossOrigin属性对应
		crossOrigin: "anonymous",
		// 设置是否横向展开世界范围，默认值为true
		// wrapX: false,
		// 切片xyz获取方法，未设置url时调用该方法
		tileUrlFunction: function (tileCoord) {
			const z = tileCoord[0];
			const x = tileCoord[1];
			const y = tileCoord[2];
			const completeUrl = url
				.replace("{z}", z.toString())
				.replace("{y}", y.toString())
				.replace("{x}", x.toString());
			return completeUrl;
		},
		// 设置投影
		projection,
		// 为服务器切片投影的平铺基类
		tileGrid: new TileGrid({
			origin: getTopLeft(projectionExtent),
			// 以像素为单位的切片大小，默认值为[256,256]
			tileSize: [256, 256],
			// 分辨率数组
			resolutions: getResolutionsExpert(size),
		}),
	});
};

// let type = "w"; // 墨卡托坐标系 EPSG:3857
// let TYPE = 'c' // WGS84 地理坐标系 EPSG:4326

// 影像底图+注记
// let IMG_C = 'img_' + TYPE
// let CIA_C = 'cia_' + TYPE

// 矢量底图+注记
// let VEC_C = 'vec_' + TYPE
// let CVA_C = 'cva_' + TYPE

// 地形晕染
// let TER_C = 'ter_' + TYPE

// 地形注记
// let CTA_C = 'cta_' + TYPE

// 境界
// let IBO_C = 'ibo_' + TYPE

export type layerType = "img_" | "cia_" | "vec_" | "cva_" | "ter_" | "cta_" | "ibo_";
type layerProj = "EPSG:3857" | "EPSG:4326";

// 根据参数获取图层
function getMLayer(type: layerType, proj: layerProj = "EPSG:4326") {
	type += proj === "EPSG:4326" ? "c" : "w";
	const layer = new LayerTile({
		source: getOptional(getUrl(type), proj),
	});
	return layer;
}

export default getMLayer;
